
public class Test {
    public static void main(String[] args) throws Exception {
        Image img = new ProxyImage("cat.jpg");
        // 此时硬盘没加载
        System.out.println("---- call display ----");
        img.display(); // 第一次才加载
        img.display(); // 直接用缓存
    }

}

// 代理模式 = “不直接找你，找你的替身”
// 替身（代理）跟原对象实现同一接口，客户端无感；代理在转调原方法前后塞入额外逻辑：延迟加载、权限、缓存、事务、日志……
// 公共接口
interface Image {
    void display();
}

// 真实对象（加载慢）
class RealImage implements Image {
    private final String file;

    RealImage(String file) {
        this.file = file;
        loadFromDisk(); // 耗时
    }

    private void loadFromDisk() {
        System.out.println("Loading " + file);
    }

    public void display() {
        System.out.println("Display " + file);
    }
}

// 代理（替身）：先不加载，等第一次 display 才建真实对象
class ProxyImage implements Image {
    private String file;
    private RealImage real; // 延迟到用的时候才 new

    ProxyImage(String file) {
        this.file = file;
    }

    public void display() {
        if (real == null)
            real = new RealImage(file); // 按需加载
        real.display();
    }
}